unit logger;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, ShlObj;

const
  //默认的日志文件尺寸上限
  MAXLOGFILESIZE = 5*1024*1024;

type

  { TLogger }
  //日志文件
  TLogger = class
  private
    FLogFileSize: Cardinal;//日志文件尺寸
    LogFile: TextFile;     //日志文件
    LogFileName: string;   //日志文件名
    FMaxFileSize: Cardinal;//日志文件尺寸上限
    FSection: string;
    procedure SetMaxFileSize(AValue: Cardinal);
  Published
    //日志文件尺寸上限
    Property MaxFileSize : Cardinal Read FMaxFileSize Write SetMaxFileSize;
  public
    constructor Create(const MaxSize: Cardinal = MAXLOGFILESIZE; Section: string = '');
    Destructor Destroy; override;
    procedure WriteLog(Text: string);
    procedure AssignLogFile;
  end;


implementation

uses FileSyncDeamon;

{ TLogger }

procedure TLogger.SetMaxFileSize(AValue: Cardinal);
begin
    if FMaxFileSize = AValue then Exit;
    if (AValue <= 0) then
        FMaxFileSize := MAXLOGFILESIZE
    else
        FMaxFileSize := AValue;
end;

constructor TLogger.Create(const MaxSize: Cardinal = MAXLOGFILESIZE; Section: string = '');
begin
    SetMaxFileSize(MaxSize);
    FSection := Section;
    AssignLogFile;
end;

destructor TLogger.Destroy;
begin
    CloseFile(LogFile);

    inherited Destroy;
end;

procedure TLogger.WriteLog(Text: string);
begin
    FLogFileSize := FLogFileSize + 21 + Length(Text);//21是日期时间的长度。TXT文件是ansi格式，不需要*2
    Writeln(LogFile, '[', FormatDateTime('yyyy-mm-dd HH:nn:ss',Now), '] ', Text);
    Flush(LogFile);

    if (MaxLogFileSize > 0) and (FLogFileSize >= MaxLogFileSize) then begin
        Writeln(LogFile, '[', FormatDateTime('yyyy-mm-dd HH:nn:ss',Now), '] 日志文件尺寸达到设定上限，切换到新文件。');
        CloseFile(LogFile);
        AssignLogFile;
    end;
end;

procedure TLogger.AssignLogFile;
var
    AppData: array [0 .. MAX_PATH] of Char;
begin
    //创建日志文件
    FLogFileSize := 0;
    try
        LogFilename := ExtractFilePath(ParamStr(0)) + 'log\';
        if not DirectoryExists(LogFilename) then
           ForceDirectories(LogFilename);
        LogFilename += FormatDateTime('yyyymmddhhnnss', Now()) + IIF('' = FSection, '', '.' + FSection) + '.log';
        AssignFile(LogFile, LogFilename);
        if FileExists(LogFilename) then
            Append(LogFile)
        else
            Rewrite(LogFile);
    except
        if S_OK = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, AppData) then begin
            LogFilename := string(AppData) + '\' + SERVICE_DESC_SHORT + '\';
            //日志保存路径不存的，先行创建
            if not DirectoryExists(LogFilename) then
                ForceDirectories(LogFilename);
            LogFilename :=  LogFilename + FormatDateTime('yyyymmddhhnnss', Now()) + IIF('' = FSection, '', '.' + FSection) + '.log';
            AssignFile(LogFile, LogFilename);
            if FileExists(LogFilename) then
                Append(LogFile)
            else
                Rewrite(LogFile);
        end;
    end;
end;

end.

